package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.logi.sys.api.domain.LogiSysUser;
import com.piggy.logi.sys.api.vo.LogiSysDeptExtVo;
import com.piggy.logi.sys.bo.LogiProjectBranchEditBo;
import com.piggy.logi.sys.bo.LogiProjectBranchQueryBo;
import com.piggy.logi.sys.bo.LogiSysDeptExtQueryBo;
import com.piggy.logi.sys.domain.LogiProjectBranch;
import com.piggy.logi.sys.mapper.LogiProjectBranchMapper;
import com.piggy.logi.sys.mapper.LogiSysDeptExtCusMapper;
import com.piggy.logi.sys.service.ILogiProjectBranchService;
import com.piggy.logi.sys.service.ILogiSysUserService;
import com.piggy.logi.sys.vo.LogiProjectBranchExtVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目承运商管理Service业务层处理
 *
 * @author piggy
 * @date 2023-08-14
 */
@Slf4j
@Service
public class LogiProjectBranchServiceImpl extends ServiceImpl<LogiProjectBranchMapper, LogiProjectBranch> implements ILogiProjectBranchService {

    @Resource
    private ILogiSysUserService userService;

    @Resource
    private LogiSysDeptExtCusMapper deptExtCusMapper;

    @Override
    public LogiProjectBranchExtVo queryById(Long id){
        LogiProjectBranchExtVo vo = getVoById(id, LogiProjectBranchExtVo.class);
        List<LogiProjectBranchExtVo> voList = fillData(Lists.newArrayList(vo));
        if (CollUtil.isNotEmpty(voList)) {
            return null;
        }
        return voList.get(0);
    }

    @Override
    public TableDataInfo<LogiProjectBranchExtVo> queryPageList(LogiProjectBranchQueryBo bo) {
        PagePlus<LogiProjectBranch, LogiProjectBranchExtVo> result = pageVo(PageUtils.buildPagePlus(bo, true), buildQueryWrapper(bo), LogiProjectBranchExtVo.class);
        result.setRecordsVo(fillData(result.getRecordsVo()));
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiProjectBranchExtVo> queryList(LogiProjectBranchQueryBo bo) {
        return fillData(listVo(buildQueryWrapper(bo), LogiProjectBranchExtVo.class));
    }

    public List<LogiProjectBranchExtVo> fillData(List<LogiProjectBranchExtVo> extVos) {

        List<Long> deptIds = extVos.stream().map(LogiProjectBranchExtVo::getBranchDeptId).distinct().collect(Collectors.toList());
        deptIds.add(-1L);

        List<Long> userIds = extVos.stream().map(LogiProjectBranchExtVo::getBranchUserId).distinct().collect(Collectors.toList());
        userIds.add(-1L);

        List<LogiSysUser> userList = userService.list(new LambdaQueryWrapper<LogiSysUser>().in(LogiSysUser::getUserId, userIds));
        LinkedHashMap<Long,LogiSysUser> userMap = userList.stream().collect(LinkedHashMap::new, (m, v) -> m.put(v.getUserId(), v), LinkedHashMap::putAll);

        LogiSysDeptExtQueryBo queryBo = (LogiSysDeptExtQueryBo) new LogiSysDeptExtQueryBo().setDeptIdList(deptIds);
        List<LogiSysDeptExtVo> deptList = deptExtCusMapper.extSysDeptList(queryBo);

        LinkedHashMap<Long,LogiSysDeptExtVo> deptMap = deptList.stream().collect(LinkedHashMap::new, (m, v) -> m.put(v.getDeptId(), v), LinkedHashMap::putAll);
        extVos = extVos.stream().peek(Any-> {
            Any.setBranchUser(userMap.get(Any.getBranchUserId()));
            Any.setBranchDept(deptMap.get(Any.getBranchDeptId()));
        }).collect(Collectors.toList());

        return extVos;
    }

    private LambdaQueryWrapper<LogiProjectBranch> buildQueryWrapper(LogiProjectBranchQueryBo bo) {
        LambdaQueryWrapper<LogiProjectBranch> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, LogiProjectBranch::getId, bo.getId());
        lqw.eq(bo.getProjectId() != null, LogiProjectBranch::getProjectId, bo.getProjectId());
        lqw.eq(bo.getBranchDeptId() != null, LogiProjectBranch::getBranchDeptId, bo.getBranchDeptId());
        lqw.eq(bo.getBranchUserId() != null, LogiProjectBranch::getBranchUserId, bo.getBranchUserId());
        lqw.in(CollUtil.isNotEmpty(bo.getProjectIdList()), LogiProjectBranch::getProjectId, bo.getProjectIdList());

        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByAddBo(LogiProjectBranchEditBo bo) {
        LogiProjectBranch add = BeanUtil.toBean(bo, LogiProjectBranch.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(LogiProjectBranchEditBo bo) {
        LogiProjectBranch update = BeanUtil.toBean(bo, LogiProjectBranch.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchByAddBo(List<LogiProjectBranchEditBo> boList) {
        if (CollUtil.isEmpty(boList)) {
            return false;
        }
        List<LogiProjectBranch> bookList = BeanUtil.copyToList(boList, LogiProjectBranch.class);
        return this.saveBatch(bookList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchByUpdateBo(List<LogiProjectBranchEditBo> boList) {
        if (CollUtil.isEmpty(boList)) {
            return false;
        }

        this.remove(Wrappers.<LogiProjectBranch>lambdaQuery().eq(LogiProjectBranch::getProjectId, boList.get(0).getProjectId()));
        return this.saveOrUpdateBatch(BeanUtil.copyToList(boList, LogiProjectBranch.class));
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(LogiProjectBranch entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }
}
